Javascript Testing

Jasmine API Example

Examples for Jasmine APIs.

Matchers

  1. .toBe() equals === in javascript
  2. .toEqual() can be used to match literal or object.
    For example,

     var a = 12;
     expect(a).toEqual(12);
    
     or
    
     var a = {
         key1 : "value1"
         key2 : "value2"
     };
    
     var b = {
         key1 : "value1"
         key2 : "value2"
     };
    
     expect(a).toEqual(b);
    
  3. toMatch() can be used to match string against regular expressions.

  4. .toBeDefined() and .toBeUndefined() are used to match against undefined
  5. .toBeNull() is used to match against null
  6. .toBeTruthy() and .toBeFalsy() are used for boolean casting testing.

     var a;
     // a = undefined, Boolean(undefined) is false
     expect(a).not.toBeTruthy();
    
     equals
    
     expect(a).toBeFalsy();
    
  7. .toContain() is used for matching an item in an array. For example,
     var array = ['item1', 'item2'];
     expect(array).contain('item1');
     expect(array).not.contain('dummy_item');
    
  8. .toBeLessThan() and .toBeGreaterThan() are used for < and > comparison.
  9. .toThrow() and .toThrowError() are used to test if a function throws an exception.

    .toThrow() tests if a function throws any exception and .toThrowError() tests if a function throws a specific exception.

    For example,

     var errorFunction = function() {
         throw new SomeError('Error Message');
     };
    
     // multiple usage
     expect(foo).toThrow();
     expect(foo).toThrowError('Error Message');
     expect(foo).toThrowError(SomeError);
     expect(foo).toThrowError(SomeError, 'Error Message');
    

Note: .not can be added before any matcher and the matcher will be evaluated to a negative assertion.

For example,

expect(12).not.toBe(13);

means

12 !== 13;

Setup and Teardown

  1. beforeEach and afterEach will be called once before and after each spec (it).
  2. beforeAll and afterAll functions will be called once before and after all specs starts and finishes, respectively.
  3. Can be used for initial settings and cleanup functions.

For example,

describe('Each', function() {
    var beforeCount = 0;
    var afterCount = 0;

    beforeEach(function() {
        beforeCount ++;
    });

    afterEach(function() {
        afterCount ++;
    });

    it('#1', function() {
        expect(beforeCount).toBe(1);
        expect(afterCount).toBe(0);
    };

    it('#2', function() {
        expect(beforeCount).toBe(2);
        expect(afterCount).toBe(1);
    };
});
describe('All', function() {
    var beforeCount = 0;
    var afterCount = 0;

    beforeAll(function() {
        beforeCount ++;
    });

    afterAll(function() {
        afterCount ++;
    });

    // beforeCount ++ here

    it('#1', function() {
        expect(beforeCount).toBe(1);
        expect(afterCount).toBe(0);
    };

    it('#2', function() {
        expect(beforeCount).toBe(1);
        expect(afterCount).toBe(0);
    };

    // afterCount ++ here
});

Spies

Test Double functions in Jasmine.

A spy only exists in the describe or it block it is defined.

  1. .toHaveBeenCalled() and toHaveBeenCalledWith() are used to test if certain function is called.
    Note that the real function is not called.

     var obj = {
         value : 0,
         setValue : function(value) {
             this.value = value;
         }
     };    
    
     beforeEach(function() {
         spyOn(obj, 'setValue');
         obj.setValue(123);
     });
    
     it('Called', function() {
         expect(obj.setValue).toHaveBeenCalled();
     });
    
     it('Called With', function() {
         expect(obj.setValue).toHaveBeenCalledWith(123);
     });
    
     // value is not set to 123 even if 
     // obj.setValue(123) is called
     it('The Real Function is no executed.', function() {
         expect(obj.value).toBe(0);
     });
    
  2. .andCallThrough to let spy not block the real function.

     beforeEach(function() {
         spyOn(obj, 'setValue').andCallThrough();
         obj.setValue(123);
     });
    
     /*
      * Other code in the last example
      */
    
     // value is set to 123 now
     it('The Real Function is executed.', function() {
         expect(obj.value).toBe(123);
     });
    

    Note: Jasmine-node use Jasmine 1.3.1.
    In Jasmine 2.0 the function is.and.callThrough()

  3. andReturn to fake the return value of some function.

     it('Fake Value is returned', function() {
         var obj = {
             getValue : function() {
                 return 0;
             }
         };
         spyOn(obj, 'getValue').andReturn(456);
         expect(obj.getValue()).toBe(456);
     });
    

    Note: Jasmine-node use Jasmine 1.3.1.
    In Jasmine 2.0 the function is.and.returnValue()

  4. andCallFake to fake a function.

     it('Fake Function is used', function() {
         var obj = {
             value : 0,
             setValue : function(value) {
                 this.value = value;
             }
         };
         spyOn(obj, 'setValue').andCallFake(function(){
             this.value = 123;
         });
         obj.setValue(456);
         expect(obj.value).toBe(123);
     });
    

References

Jasmine 1.3

Example Project